#include <iostream>

using namespace std;

template <typename T>
class smart_ptr
{
  smart_ptr(smart_ptr &other) { ptr_ = other.release(); }

  smart_ptr &operator=(smart_ptr &rhs)
  {
    // 在拷贝构造函数中，通过调用 other 的 release 方法来释放它对指针的所有权。在赋值函数中，则通过拷贝构造产生一个临时对象并调用 swap 来交换对指针的所有权。实现上是不复杂的。如果你学到的赋值函数还有一个类似于 if (this != &rhs) 的判断的话，那种用法更啰嗦，而且异常安全性不够好——如果在赋值过程中发生异常的话，this 对象的内容可能已经被部分破坏了，对象不再处于一个完整的状态。目前这种惯用法（见参考资料[1] ）则保证了强异常安全性：赋值分为拷贝构造和交换两步，异常只可能在第一步发生；而第一步如果发生异常的话，this 对象完全不受任何影响。无论拷贝构造成功与否，结果只有赋值成功和赋值没有效果两种状态，而不会发生因为赋值破坏了当前对象这种场景。如果你觉得这个实现还不错的话，那恭喜你，你达到了 C++ 委员会在 1998 年时的水平：上面给出的语义本质上就是 C++ 98 的 auto_ptr 的定义。如果你觉得这个实现很别扭的话，也恭喜你，因为 C++ 委员会也是这么觉得的：auto_ptr 在 C++ 17 时已经被正式从 C++ 标准里删除了。上面实现的最大问题是，它的行为会让程序员非常容易犯错。一不小心把它传递给另外一个 smart_ptr，你就不再拥有这个对象了...... 1011121314151617181920212223242526 smart_ptr(rhs).swap(*this);
    return *this;
  }

  T *release()
  {
    T *ptr = ptr_;
    ptr_ = nullptr;
    return ptr;
  }

  void swap(smart_ptr &rhs)
  {
    using std ::swap;
    swap(ptr_, rhs.ptr_);
  }
}